package com.gm.wj.service;

import com.gm.wj.config.RedisConfig;
import com.gm.wj.dao.SysMessageDAO;
import com.gm.wj.entity.SysMessage;
import com.gm.wj.redis.RedisService;
import com.gm.wj.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.*;

/**
 * @program: wj
 * @description:
 * @author: Huang_shengjun
 * @create: 2020-08-31 15:28
 **/
@Slf4j
@Service
public class SysMessageService {

    @Autowired
    SysMessageDAO sysMessageDAO;
    @Autowired
    RedisService redisService;
    @Autowired
    PermissionURL permissionURL;

    // 发送邮件正文+附件
    public String sendMailAndAppendix(SysMessage sysMessage) {
        // 获取操作用户名
        String username = (String) SecurityUtils.getSubject().getPrincipal();

        // 发送成功失败与否，都会记录下来
        sysMessage.setCreateTime(MyTime.getStringDate());
        sysMessage.setSendType(0); // 0-邮箱；1-短信
        sysMessage.setSendUsername(username);
        try {
            SendByEmailTools.sendMailAndAppendix(sysMessage.getReceiveNum(), sysMessage.getSubject(), sysMessage.getContent(), sysMessage.getFilename());
            sysMessage.setIsSuccess(1); // 0-失败；1-成功；
            addOrUpdate(sysMessage);
            return "1";
        } catch (Exception e){
            sysMessage.setIsSuccess(0); // 0-失败；1-成功；
            addOrUpdate(sysMessage);
            return e.getMessage();
        }

    }

    // 订单完成之后  发送邮箱
    public String sendMailToOrder(String user, String orderId, String email, String time, String courserName, String teacher, String amount) {
        SysMessage sysMessage = new SysMessage();
        String subject = "【教育培训机构】 订单";
        // 发送成功失败与否，都会记录下来
        sysMessage.setCreateTime(MyTime.getStringDate());
        sysMessage.setSendType(0); // 0-邮箱；1-短信
        sysMessage.setSendUsername(user);
        sysMessage.setReceiveUsername(user);
        sysMessage.setContent("【支付成功】订单ID：" + orderId);
        sysMessage.setReceiveNum(email);
        sysMessage.setSubject(subject);
        try {
            SendByEmailTools.sendMailToOrder( user, orderId, email, time, courserName, teacher, amount,subject);
            sysMessage.setIsSuccess(1); // 0-失败；1-成功；
            addOrUpdate(sysMessage);
            return "1";
        } catch (Exception e){
            sysMessage.setIsSuccess(0); // 0-失败；1-成功；
            addOrUpdate(sysMessage);
            return e.getMessage();
        }
    }

    // 单单发送邮件
    public String sendEmail(SysMessage sysMessage) {
        // 获取操作用户名
        String username = (String) SecurityUtils.getSubject().getPrincipal();

        // 发送成功失败与否，都会记录下来
        sysMessage.setCreateTime(MyTime.getStringDate());
        sysMessage.setSendType(0); // 0-邮箱；1-短信
        sysMessage.setSendUsername(username);

        try {
            SendByEmailTools.sendMail(sysMessage.getReceiveNum(), sysMessage.getSubject(), sysMessage.getContent());
            sysMessage.setIsSuccess(1); // 0-失败；1-成功；
            addOrUpdate(sysMessage);
            return "1";
        } catch (Exception e){
            sysMessage.setIsSuccess(0); // 0-失败；1-成功；
            addOrUpdate(sysMessage);
            return e.getMessage();
        }
    }

    // 发送手机信息
    public String sendPhone(SysMessage sysMessage) {
        // 获取操作用户名
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        String message = SendByPhoneUtil.twilioPhoneCode(sysMessage.getReceiveNum(), sysMessage.getContent());
        // 发送成功失败与否，都会记录下来
        sysMessage.setCreateTime(MyTime.getStringDate());
        sysMessage.setSendType(1); // 0-邮箱；1-短信
        sysMessage.setSendUsername(username);
        // 将主题和附件内容设为空
        sysMessage.setSubject("");
        sysMessage.setFilename("");

        if ( message == "1" ) {
            sysMessage.setIsSuccess(1); // 0-失败；1-成功；
            addOrUpdate(sysMessage);
            return "1";
        } else {
            sysMessage.setIsSuccess(0); // 0-失败；1-成功；
            addOrUpdate(sysMessage);
            return message;
        }
    }

    public MyPage list(int page, int size, String queryKey1, String queryKey2, String queryKey3, String queryKey4, String queryKey5) {
        // 获取操作用户名
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        MyPage<SysMessage> sysMessages;
        // list缓存
        String key =  username + "messagepage:" + page;
        Object pageCache = redisService.get(key);

        // 如果为空，就再查询一次，写入redis缓存
        if (pageCache == null) {
            Sort sort = Sort.by(Sort.Direction.DESC, "id");

            // 重写 findAll方法  多条件查询
            Pageable pageable = new PageRequest(page, size,sort);
            Page<SysMessage> messageInDb = sysMessageDAO.findAll((Specification<SysMessage>) (root, criteriaQuery, criteriaBuilder) -> {
                List<javax.persistence.criteria.Predicate> list = new ArrayList<Predicate>();
                // 实体类字段，不是数据库字段
                list.add(criteriaBuilder.equal(root.get("receiveUsername").as(String.class), username));
                // 如果拥有权限  清除只能查询自己的数据的条件查询
                if(permissionURL.isPermissionURL(SysMessage.class.getSimpleName(),username)){
                    list.removeAll(list);
                }
                if(!"".equals(queryKey2)&&null!=queryKey2){
                    list.add(criteriaBuilder.like(root.get("subject").as(String.class), "%" + queryKey2 + "%"));
                }
                if(!"".equals(queryKey3)&&null!=queryKey3){
                    list.add(criteriaBuilder.like(root.get("content").as(String.class), "%" + queryKey3 + "%"));
                }
                if(!"".equals(queryKey4)&&null!=queryKey4){
                    list.add(criteriaBuilder.equal(root.get("isSuccess").as(String.class), queryKey4 ));
                }
                if(!"".equals(queryKey5)&&null!=queryKey5){
                    list.add(criteriaBuilder.equal(root.get("sendType").as(String.class), queryKey5 ));
                }
                javax.persistence.criteria.Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            },pageable);
            // findAll方法 重写结束

            sysMessages = new MyPage<>(messageInDb);
            // 设置redis过期时间  5s
            redisService.set(key, sysMessages, RedisConfig.DATA_REDIS_KEY_TIME);
        } else {
            sysMessages = (MyPage<SysMessage>) pageCache;
        }
        return sysMessages;
    }

    public void addOrUpdate(SysMessage sysMessage) {
//        sysMessage.setCreateTime( MyTime.getStringDate());
        sysMessageDAO.save(sysMessage);
        redisService.delete("message" + sysMessage.getId());
        Set<String> keys = redisService.getKeysByPattern("messagepage*");
        redisService.delete(keys);
    }

    public List<SysMessage> listByQueryKey(String queryKey1, String queryKey2, String queryKey3, String queryKey4, String queryKey5) {

        // 多条件模糊查询
        queryKey1 = (queryKey1 == null) ? null : "%" + queryKey1 + "%";
        queryKey2 = (queryKey2 == null) ? null : "%" + queryKey2 + "%";
        queryKey3 = (queryKey3 == null) ? null : "%" + queryKey3 + "%";
        queryKey4 = (queryKey4 == null && queryKey4 == "" ) ? null : "" + queryKey4 + ""; // booble值  直接用等于  不用like了
        queryKey5 = (queryKey5 == null && queryKey5 == "" ) ? null : "" + queryKey5 + ""; // booble值  直接用等于  不用like了
        List<SysMessage> sysMessages = sysMessageDAO.find(queryKey1, queryKey2, queryKey3,queryKey4,queryKey5);

        return sysMessages;

    }

    // 效验邮箱、电话号码
    public int verifyCode(SysMessage sysMessage) {
        if (sysMessage.getSendType() == 0 ) {
            if (VerifyUtils.isEmail(sysMessage.getReceiveNum())) {
                return 0; // 效验邮箱正确，返回0
            }
            return 1;  // 效验邮箱错误
        }
        if (sysMessage.getSendType() == 1 ) {
            if (VerifyUtils.isMobileNO(sysMessage.getReceiveNum())) {
                return 2;  // 效验手机正确
            }
            return 3;  // 效验手机错误
        }
        return 4;  // 没有选择发送类型
    }

    // 发送成功的消息数量
    public Map<String,Integer> findMessageData() {
        Map<String, Integer> map = new HashMap<>();

        int MessageDataNum = sysMessageDAO.findMessageData(); // 总消息数
        int MessageDataByPhoneNum = sysMessageDAO.findMessageDataByphone(); // 发送成功的消息数量 短信
        int MessageDataByEmailNum = sysMessageDAO.findMessageDataByemail(); // 发送成功的消息数量 邮箱

        map.put("MessageDataNum", MessageDataNum);
        map.put("MessageDataByPhoneNum", MessageDataByPhoneNum);
        map.put("MessageDataByEmailNum", MessageDataByEmailNum);
        return map;
    }

}
